/*
 * Toedo
 * Copyright (C) 2009-2010 J. Devauchelle and contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 3 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package org.toedo.model;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.toedo.controllers.DataController;

public class Task extends BaseNote {
	
	public enum TaskStatus {
		EnOpen,
		EnClosed
	}
	
	private int mPriority;
	private Date mStartDate;
	private Date mDueDate;
	private TaskStatus mStatus;
	
	public Task(String title) {
		super(title);
		
		mPriority = DataController.getInstance().getProject().getDefaultPriority();
		
		mStartDate = getDefaultStartDate();
		mDueDate = getDefaultDueDate();
		
		mStatus = TaskStatus.EnOpen;
	}
	
	public Task(String title, String content, Date startDate, Date dueDate, int priority) {
		this(title);
		setContent(content);
		mStartDate = startDate;
		mDueDate = dueDate;
		mPriority = priority;
	}
	
	@Override
	protected Object readResolve() {
		mNeedContentRefresh = true;
		return super.readResolve();
	}
	
	public static Date getDefaultStartDate() {
		Calendar cal = new GregorianCalendar();
		cal.setTime(new Date());
		setCalendarAtMidnight(cal);
		
		cal.add(Calendar.DAY_OF_MONTH, DataController.getInstance().getProject().getStartDateDelay());
		
		return cal.getTime();
	}
	
	public static Date getDefaultDueDate() {
		Calendar cal = new GregorianCalendar();
		cal.setTime(getDefaultStartDate());
		cal.add(Calendar.DAY_OF_MONTH, DataController.getInstance().getProject().getDefaultDuration());
		setCalendarAtEndOfDay(cal);
		
		return cal.getTime();
	}
	
	public int getPriority() {
		return mPriority;
	}
	
	public void setPriority(int value) {
		mPriority = value;
	}
	
	public Date getStartDate() {
		return mStartDate;
	}
	
	public void setStartDate(Date value) {
		mStartDate = value;
	}
	
	public Date getDueDate() {
		return mDueDate;
	}
	
	public void setDueDate(Date value) {
		mDueDate = value;
	}
	
	public TaskStatus getStatus() {
		return mStatus;
	}
	
	public void setStatus(TaskStatus value) {
		mStatus = value;
	}
	
	protected void addTag(Tag tag) {
		if (!mTagsList.contains(tag)) {
			
			mTagsList.add(tag);
			tag.addTask(this);
			
		}
	}
	
	protected void removeTag(Tag tag) {
		if (mTagsList.contains(tag)) {
			
			mTagsList.remove(tag);			
			tag.removeTask(this);
			
		}
	}

	public boolean isLate() {
		Calendar cal = new GregorianCalendar();
		cal.setTime(new Date());		
		
		return mDueDate.before(cal.getTime());
	}
	
	public boolean isUrgent() {
		/*
		Calendar cal = new GregorianCalendar();
		cal.setTime(new Date());
		
		cal.add(Calendar.DAY_OF_MONTH, DataController.getInstance().getProject().getUrgentDelay());
		return mDueDate.before(cal.getTime());
		*/
		return getDeltaInDays() <= DataController.getInstance().getProject().getUrgentDelay();
	}
	
	public boolean isDueForToday() {
		Calendar cal = new GregorianCalendar();
		
		cal.setTime(new Date());
		setCalendarAtMidnight(cal);
		
		Date today = cal.getTime();
		
		cal.setTime(mDueDate);
		setCalendarAtMidnight(cal);
		
		return today.equals(cal.getTime());
	}
	
	public boolean isStartingToday() {
		Calendar cal = new GregorianCalendar();
		
		cal.setTime(new Date());
		setCalendarAtMidnight(cal);
		
		Date today = cal.getTime();
		
		cal.setTime(mStartDate);
		setCalendarAtMidnight(cal);
		
		return today.equals(cal.getTime());
	}
	
	private static void setCalendarAtMidnight(Calendar cal) {
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
	}
	
	private static void setCalendarAtEndOfDay(Calendar cal) {
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
	}
	
	public int getDeltaInDays() {
		long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
		
		Calendar nowDate = new GregorianCalendar();
		nowDate.setTime(new Date());
		
		Calendar calDueDate = new GregorianCalendar();
		calDueDate.setTime(mDueDate);
		
		long endL = calDueDate.getTimeInMillis() + calDueDate.getTimeZone().getOffset(calDueDate.getTimeInMillis());
        long startL = nowDate.getTimeInMillis() + nowDate.getTimeZone().getOffset( nowDate.getTimeInMillis() );
        
        return (int) ((endL - startL) / MILLISECS_PER_DAY);
	}

}
